from .base_strategy import BaseStrategy
import backtrader as bt
###
# 使用布林带（MID=12,STD=2）  
# 当价格 上穿中轨，并且随后2根k线均为阳线，则开多单，使用2%进行移动止盈止损，
# 空单则相反，当价格下穿中轨，且随后2根k线为阴线，则开空，也是最大2%回撤 止盈止损
# #
class MyStrategy(BaseStrategy):
    params = (
     ('bb_period', 12),       # 布林带周期
        ('bb_dev', 2.0),         # 标准差倍数
        ('risk_pct', 0.02),      # 风险比例(2%)
        ('risk_pct2', 0.1),      # 风险比例(2%)
        ('debug', False),        # 调试模式
        ('printlog', False)      # 打印交易日志
    )
 
    def __init__(self):
        super().__init__()

        self.init_indicators()

        # 用于跟踪订单
        self.order = None        # 跟踪订单
        self.entry_price2 =  0    # 入场价格
        self.stop_price =  0      # 止损价格
        self.take_profit = 0    # 止盈价格
    
    def init_indicators(self):
        """在此定义指标 (EMA/MACD/RSI等)"""
        # 布林带指标
        self.bb = bt.indicators.BollingerBands(
            self.data.close, 
            period=self.p.bb_period, 
            devfactor=self.p.bb_dev
        )
        
        # 检查中轨穿越
        self.cross = bt.indicators.CrossOver(self.data.close, self.bb.mid) # 金叉死叉信号



    def notify_order(self, order):
        super().notify_order(order)

        if order.status in [order.Submitted, order.Accepted]:
            # 订单已提交/接受 - 不做任何操作
            return
        
        # 重置订单
        self.order = None

    def next(self):
        super().next()
        if(len(self)<3):
            return
        # 检查是否有进行中的订单
        if self.order:
            return
        
        yinyang = [0,0,0]
        # 计算最近3根k线颜色
        yinyang[0] = -1 if self.data.open[-2]  > self.data.close[-2] else 1
        yinyang[1] = -1 if self.data.open[-1]  > self.data.close[-1] else 1
        yinyang[2] = -1 if self.data.open[0]  > self.data.close[0] else 1

        buyStatus = self.cross[-2]==1 and yinyang == [1,1,1]
        sellStatus = self.cross[-2]==-1 and yinyang == [-1,-1,-1]
        
        # 如果没有持仓
        if not self.position:
            # 做多条件：上穿中轨且随后2根阳线
            if buyStatus:
                self.entry_price2 = self.data.close[0]
                self.buy()  # 开多单
                # 设置初始止损止盈(2%)
                self.stop_price = self.entry_price2 * (1 - self.p.risk_pct)
                self.take_profit = self.entry_price2 * (1 + self.p.risk_pct2)

            
            # 做空条件：下穿中轨且随后2根阴线
            elif sellStatus:
                self.entry_price2 = self.data.close[0]
                self.sell() # 开空单
                # 设置初始止损止盈(2%)
                self.stop_price = self.entry_price2 * (1 + self.p.risk_pct)
                self.take_profit = self.entry_price2 * (1 - self.p.risk_pct2)

        
        # 如果有持仓，更新移动止损
        else:
            # 多头仓位
            if self.position.size > 0:
                # 更新止损（最高价的2%回撤）
                new_stop = self.data.high[0] * (1 - self.p.risk_pct)
                self.stop_price = max(self.stop_price, new_stop)
                # 检查止损或止盈
                if self.data.close[0] <= self.stop_price or self.data.close[0] >= self.take_profit:
                    # print(f"{self.data.datetime.datetime(0)}  平多单 最低价{self.data.low[0]} 止损价{ self.stop_price} 止盈价格{self.take_profit}")
                    self.close()
            
            # 空头仓位
            elif self.position.size < 0:
                # 更新止损（最低价的2%回撤）
                new_stop = self.data.low[0] * (1 + self.p.risk_pct)
                self.stop_price = min(self.stop_price, new_stop)
                # 检查止损或止盈
                if self.data.close[0] >= self.stop_price or self.data.close[0] <= self.take_profit:
                    print(f"{self.data.datetime.datetime(0)}  平空单 最低价{self.data.low[0]} 止损价{ self.stop_price} 止盈价格{self.take_profit}")
                    self.close()



    def calculate_size(self):
        # 计算头寸规模，确保风险不超过账户的2%
        risk_amount = self.broker.getvalue() * self.p.risk_pct
        risk_per_share = abs(self.entry_price2 - self.stop_price)
        size = int(risk_amount / risk_per_share)
        return size
    
    def notify_order(self, order):
        super().notify_order(order)
        if order.status in [order.Submitted, order.Accepted]:
            return  # 订单已提交/接受 - 不做任何操作
        
        self.order = None